package com.ruibang.glass.material.controller.warehousemanage;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.resource.ClassPathResource;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruibang.glass.common.constants.RedisKey;
import com.ruibang.glass.material.constant.MaterialErrorCode;
import com.ruibang.glass.material.constant.MaterialWareHouseCode;
import com.ruibang.glass.material.domain.req.MaterialManagementReq;
import com.ruibang.glass.material.entity.MaterialManagement;
import com.ruibang.glass.material.entity.MaterialWarehouseInfo;
import com.ruibang.glass.material.service.GMaterialManagementService;
import com.ruibang.glass.material.service.MaterialWarehouseInfoService;
import com.teaming.cloud.framework2.autoconfigure.redis.RedisSingleService;
import com.teaming.cloud.framework2.common.exception.ServiceException;
import com.teaming.cloud.framework2.common.model.ResultBody;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 物料管理 前端控制器
 * </p>
 *
 * @author mameng
 * @since 2024-02-05
 */
@Api(tags = "物料管理")
@RestController
@RequestMapping("/api/glass/material/management/")
public class MaterialManagementController {


    @Autowired
    private GMaterialManagementService materialManagementService;

    @Autowired
    private MaterialWarehouseInfoService warehouseInfoService;

    @Autowired
    private RedisSingleService rediservice;

    @PostMapping("/list")
    @ApiOperation(value = "获取物料信息列表", response = ResultBody.class)
    public ResultBody getPageList(@RequestBody MaterialManagementReq materialManagementReq) {
        return ResultBody.success(materialManagementService.getPage(materialManagementReq));
    }

    @PostMapping("/add")
    @ApiOperation(value = "新增", response = ResultBody.class)
    public ResultBody add(@RequestBody MaterialManagement materialManagement) {
        materialManagementService.add(materialManagement);
        return ResultBody.success();
    }


    @PostMapping("/update")
    @ApiOperation(value = "新增", response = ResultBody.class)
    public ResultBody updateMaterialManagement(@RequestBody MaterialManagement materialManagement) {
        materialManagementService.updateById(materialManagement);
        return ResultBody.success();
    }

    @GetMapping("/getOne/{id}")
    @ApiOperation(value = "查询", response = ResultBody.class)
    public ResultBody getOne(@PathVariable("id") String id) {
        MaterialManagement management = materialManagementService.getById(id);
        if (management != null) {
            MaterialWarehouseInfo info = warehouseInfoService.getOne(Wrappers.<MaterialWarehouseInfo>lambdaQuery()
                    .select(MaterialWarehouseInfo::getWarehouseName,
                            MaterialWarehouseInfo::getId).eq(MaterialWarehouseInfo::getId, management.getRequiredWarehouseId()).eq(MaterialWarehouseInfo::getWarehouseCode, management.getWarehouseCode()));
            if (info != null) {
                management.setWarehouseName(info.getWarehouseName());
                management.setWarehouseId(info.getId());
            }
        }
        return ResultBody.success(management);
    }

    @PostMapping("/getWarehouseByIds")
    @ApiOperation(value = "根据物品Id查询对应仓库列表", response = ResultBody.class)
    public ResultBody getWarehouseByIds(@RequestBody List<String> itemIds) {
        return ResultBody.success(materialManagementService.getWarehouseByIds(itemIds));
    }


    @GetMapping("/getNameList/{id}")
    @ApiOperation(value = "根据仓库获取物品", response = ResultBody.class)
    public ResultBody getNameList(@PathVariable("id") String id) {
        MaterialWarehouseInfo byId = warehouseInfoService.getById(id);
        if (byId != null) {
            List<MaterialManagement> list = materialManagementService.list(
                    Wrappers.<MaterialManagement>lambdaQuery().select(MaterialManagement::getId, MaterialManagement::getItemName,
                            MaterialManagement::getSpecificationModel,
                            MaterialManagement::getMaterialCode, MaterialManagement::getUnit
                    ).eq(MaterialManagement::getWarehouseCode, byId.getWarehouseCode()));
            return ResultBody.success(list);
        }

        return ResultBody.success();
    }

    @PostMapping("/materialChoose")
    @ApiOperation(value = "获取物料下拉", response = ResultBody.class)
    public ResultBody materialChoose(@RequestBody MaterialManagementReq materialManagementReq) {
        return ResultBody.success(materialManagementService.queryMaterialChoose(materialManagementReq));
    }

    @GetMapping("/getMaterialInfo")
    @ApiOperation(value = "获取物料信息", response = ResultBody.class)
    public ResultBody getMaterialInfo() {
        return ResultBody.success(materialManagementService.getMaterialInfo());
    }


    @GetMapping("/materialYCLChoose")
    @ApiOperation(value = "获取原材料物料下拉", response = ResultBody.class)
    public ResultBody getYclSelect() {
        List<MaterialManagement> list = materialManagementService.list(
                Wrappers.<MaterialManagement>lambdaQuery().eq(MaterialManagement::getWarehouseCode, MaterialWareHouseCode.YCLK_CK.getMsg()));
        return ResultBody.success(list);
    }

    @PostMapping("/getMaterialManagerByIds")
    @ApiOperation(value = "根据id列表查询物料列表信息", response = ResultBody.class)
    public ResultBody getMaterialManagerByIds(@RequestBody List<String> ids) {
        List<MaterialManagement> list = materialManagementService.list(
                Wrappers.<MaterialManagement>lambdaQuery().select(MaterialManagement::getId, MaterialManagement::getItemName, MaterialManagement::getSpecificationModel, MaterialManagement::getUnit, MaterialManagement::getItemType,
                        MaterialManagement::getMaterialCode, MaterialManagement::getBarcode, MaterialManagement::getBarcode, MaterialManagement::getApplyUser,MaterialManagement::getWarehouseCode).in(MaterialManagement::getId, ids));
        return ResultBody.success(list);
    }

    @GetMapping("/materialCPORBCPChoose/{warehouseCode}")
    @ApiOperation(value = "成品半成品下拉", response = ResultBody.class)
    public ResultBody materialCPORBCPChoose(@PathVariable("warehouseCode") String warehouseCode) {
        List<MaterialManagement> list = materialManagementService.list(
                Wrappers.<MaterialManagement>lambdaQuery().select(MaterialManagement::getMaterialCode, MaterialManagement::getId, MaterialManagement::getItemName, MaterialManagement::getSpecificationModel,
                        MaterialManagement::getRequiredWarehouse,
                        MaterialManagement::getRequiredWarehouseId,
                        MaterialManagement::getUnit
                )
                        .eq(MaterialManagement::getWarehouseCode, warehouseCode));
        return ResultBody.success(list);
    }


    @PostMapping("importExcel")
    @ApiOperation(value = "导入", response = ResultBody.class)
    @Transactional(rollbackFor = Exception.class)
    public ResultBody importExcel(@RequestPart("files") MultipartFile file, HttpServletRequest request) {
        Map<String, String> dictMap = materialManagementService.getDictMap();
        List<String> itemReturnList = new ArrayList<>();
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String contentType = file.getContentType();
        System.out.println("文件类型是===========" + contentType);
        String fileName = file.getOriginalFilename();
        System.out.println("文件名字是===========" + fileName);
        if (file.isEmpty()) {
            return ResultBody.fail(310, "文件为空！");
        }
        //根据路径获取这个操作excel的实例
        XSSFWorkbook wb = null;
        try {
            wb = new XSSFWorkbook(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //根据页面index 获取sheet页
        Sheet sheet = wb.getSheetAt(0);
        //获取sheet页共有多少行
        int totalRos = sheet.getPhysicalNumberOfRows();
        System.out.println("=========总行数为：" + totalRos);
        if (totalRos < 2) {
            throw new ServiceException(MaterialErrorCode.EXPORT_FAILD_ONLYTITLE.getCode(), MaterialErrorCode.EXPORT_FAILD_ONLYTITLE.getMsg());
        }
        // 校验物料code唯一
        List<MaterialManagement> list = materialManagementService.list(Wrappers.<MaterialManagement>lambdaQuery().select(MaterialManagement::getMaterialCode).isNotNull(MaterialManagement::getMaterialCode));
        Map<String, String> itemCodeMap = new HashMap<>();
        for (MaterialManagement materialManagement : list) {
            itemCodeMap.put(materialManagement.getMaterialCode(), materialManagement.getMaterialCode());
        }
        for (int i = 1; i < totalRos; i++) {
            MaterialManagement materialManagement = new MaterialManagement();
            if (sheet.getRow(i).getCell(0) != null) {
                materialManagement.setMaterialCode(sheet.getRow(i).getCell(0).toString());
            }
            if (sheet.getRow(i).getCell(1) != null) {
                materialManagement.setItemName(sheet.getRow(i).getCell(1).toString());
            }
            if (sheet.getRow(i).getCell(2) == null) {
                throw new ServiceException(MaterialErrorCode.EXPORT_FAILD_NO_UNIT.getCode(), MaterialErrorCode.EXPORT_FAILD_NO_UNIT.getMsg());
            } else {
                if (dictMap.get(sheet.getRow(i).getCell(2).toString()) == null) {
                    throw new ServiceException(MaterialErrorCode.EXPORT_FAILD_DICT_NO_UNIT.getCode(), MaterialErrorCode.EXPORT_FAILD_NO_UNIT.getMsg() + "单位为:   " + sheet.getRow(i).getCell(2).toString() + "字典表中暂无数据！请检查字典表");
                } else {
                    materialManagement.setUnit(sheet.getRow(i).getCell(2).toString());
                }
            }
            if (sheet.getRow(i).getCell(3) != null) {
                materialManagement.setSpecificationModel(sheet.getRow(i).getCell(3).toString());
            }
            for (MaterialWareHouseCode ele : MaterialWareHouseCode.values()) {
                if (sheet.getRow(i).getCell(4)!=null){
                    if (ele.getName().equals(sheet.getRow(i).getCell(4).toString())) {
                        materialManagement.setRequiredWarehouse(ele.getName());
                        materialManagement.setWarehouseId(ele.getName());
                        materialManagement.setWarehouseName(ele.getName());
                        materialManagement.setRequiredWarehouseId(ele.getWareId());
                        materialManagement.setWarehouseCode(ele.getMsg());
                    }
                }
            }
            if (sheet.getRow(i).getCell(6) != null) {
                materialManagement.setStalePeriod(Integer.parseInt(sheet.getRow(i).getCell(6).toString().replace(".0", "")));
            }
            if (sheet.getRow(i).getCell(5) != null) {
                materialManagement.setBarcode(sheet.getRow(i).getCell(5).toString());
            }
            if (itemCodeMap.get(materialManagement.getMaterialCode()) != null) {
                itemReturnList.add(materialManagement.getMaterialCode());
            } else {
                itemCodeMap.put(materialManagement.getMaterialCode(), materialManagement.getMaterialCode());
                if (StringUtils.isNotBlank(materialManagement.getRequiredWarehouseId()) && StringUtils.isNotBlank(materialManagement.getMaterialCode()) && StringUtils.isNotBlank(materialManagement.getItemName())) {
                    materialManagementService.save(materialManagement);
                }else {
                    itemReturnList.add(materialManagement.getMaterialCode());
                }
            }
        }
        return ResultBody.success(itemReturnList);

    }


    @GetMapping("getFile")
    @ApiOperation(value = "模版下载", response = ResultBody.class)
    @ResponseBody
    public void getFile(HttpServletResponse response) {
        // 使用 ClassPathResource 的 getInputStream() 方法获取输入流
        try (
                InputStream inputStream = new ClassPathResource("/file/物料导入模版.xls").getStream();
                ServletOutputStream outputStream = response.getOutputStream()) {

            // 设置文件下载方式
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode("物料导入模版.xls", "UTF-8"));
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 设置正确的 MIME 类型
            // 流数据交换，每次交换10k数据大小
            byte[] bytes = new byte[1024 * 10];
            int read;
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }

            // 不需要显式关闭流，因为 try-with-resources 会自动处理
        } catch (IOException e) {
            // 处理异常，可能需要记录日志或返回错误响应
            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }

    }
}
